/**
 * Clase Main: Contiene el programa principal
 *
 * Autores: Christian Chomiak (05-38034)
 *          Miguel De Los Ríos (05-38084)
 */
package kraken;

import java.io.*;
import java.util.*;
import java.net.*;

public class Main {

    public static void main(String[] args) {
        Thread proxy_manager = new Thread(new ProxyManager());
        proxy_manager.start();
        ProgramaPrincipal();

    }

    /*
     * Función ProgramaPrincipal(): Función que corre en el hilo principal del
     * programa y que se encarga de recibir las entradas del usuario del proxy.
     * Los hilos secundarios se encargan de correr el HTTP Proxy como tal.
     */
    public static void ProgramaPrincipal() {
        boolean exit = false;
        String comando = null;

        System.out.println("*****************************");
        System.out.println("*****************************");
        System.out.println("**    KRAKEN PROXY 1.0     **");
        System.out.println("** Por: Christian Chomiak  **");
        System.out.println("**      Miguel De Los Ríos **");
        System.out.println("*****************************");
        System.out.println("*****************************\n\n");

        System.out.println("Escriba h, help o ? para ver los comandos disponibles.\n");
        while (!exit) {
            comando = Console.readString(">");
            exit = ProcesarComando(comando);
        }
    }

    /*
     * Función ProcesarComando(comando): Determina si el comando es válido o no.
     * De ser así determina la estadística a obtener.
     */
    public static boolean ProcesarComando(String comando) {
        String[] command = comando.split(" ");
        List<String> Comandos = Arrays.asList("topsites", "users_sites", "denied", "h", "help", "?", "exit");
        if (!Comandos.contains(command[0])) {
            System.out.println("El comando " + command[0] + " es invalido. Escriba h, help o ? para ver los comandos disponibles.\n");
        } else if (command.length < 1) {
        } else if (command[0].equals("topsites")) {
            if (command.length > 1) {
                System.out.println("El comando topsites no necesita argumentos\n");
            } else {
                List<Estadistica> topsites = Estadistica.TopSites();
                ImprimirTopSites(topsites);
            }
        }else if (command[0].equals("users_sites")) {
            if (command.length == 1) {
                System.out.println("No se introdujo la direccion ip del usuario\n");
            } else if (command.length > 2) {
                System.out.println("Demasiados argumentos para el comando users_sites");
            } else {
                List<Estadistica> usersites = Estadistica.UserSites(command[1]);
                ImprimirUserSites(usersites, command[1]);
            }
        } else if (command[0].equals("denied")) {
            if (command.length > 1) {
                System.out.println("El comando sites_users no necesita argumentos\n");
            } else {
                List<Estadistica> denied = Estadistica.denied();
                ImprimirDenied(denied);
            }
        } else if (command[0].equals("exit")) {
            if (command.length > 1) {
                System.out.println("El comando exit no necesita argumentos\n");
            } else {
                return true;
            }
        } else {
            if (command.length > 1) {
                System.out.println("El comando help no necesita argumentos\n");
            } else {
                Help();
            }
        }
        return false;
    }

    public static void ImprimirTopSites(List<Estadistica> topSites) {
        System.out.println("Sitios mas visitados:");
        InetAddress addr;
        String hostname;
        System.out.println("Pos | Nombre del Sitio | Numero de Visitas");
        for (int i = 0; i < topSites.size(); i++) {
            //Obtiene el nombre del sitio
            try {
                addr = InetAddress.getByName(topSites.get(i).getHost());
                hostname = addr.getHostName();
            } catch (UnknownHostException e) {
                hostname = topSites.get(i).getHost();
            }
            System.out.println((i + 1) + ".- | " + hostname + " | " + topSites.get(i).getNumVisitas());
        }
    }

    public static void ImprimirUserSites(List<Estadistica> usersites, String usuario){
        System.out.println("Sitios visitados por el usuario " + usuario + ":");
        InetAddress addr;
        String hostname;
        System.out.println("Pos | Nombre del Sitio | Numero de Visitas");
        for (int i = 0; i < usersites.size(); i++) {
            //Obtiene el nombre del sitio
            try {
                addr = InetAddress.getByName(usersites.get(i).getHost());
                hostname = addr.getHostName();
            } catch (UnknownHostException e) {
                hostname = usersites.get(i).getHost();
            }
            System.out.println((i + 1) + ".- | " + hostname + " | " + usersites.get(i).getNumVisitas());
        }
    }

    public static void ImprimirDenied(List<Estadistica> denied){
        System.out.println("Intentos de conexion denegados:");
        InetAddress addr;
        String hostname;
        String canhost;
        System.out.println("Pos | Nombre del Sitio | Intentos de conexion");
        for (int i = 0; i < denied.size(); i++) {
            //Obtiene el nombre del sitio
            try {
                addr = InetAddress.getByName(denied.get(i).getHost());
                hostname = addr.getHostName();
                canhost = addr.getCanonicalHostName();
            } catch (UnknownHostException e) {
                hostname = denied.get(i).getHost();
                canhost = hostname;
            }
            System.out.println((i + 1) + ".- | " + canhost + " | " + denied.get(i).getNumVisitas());
        }
    }

    public static void Help() {
        System.out.println("Comandos de Kraken 1.0:");
        System.out.println("topsites: Muestra los 10 sitios mas visitados, junto con su numero de visitas");
        System.out.println("users_sites <ip> Muestra los sitios visitados por el usuario con la direccion ip especificada");
        System.out.println("denied: Indica los intentos de conexiones que han sido rechazados por el HTTP Proxy");
        System.out.println("help/h/?: Ayuda");
        System.out.println("exit: Salir");
    }
}
